// 车辆磨损
// 时间限制： 1000MS
// 内存限制： 65536KB
// 题目描述：
// 小程开车自驾游穿越一片山区，我们把这座山看作是n*m的方格构成的区域，每个方格有自己的高度h。在同一高度的方格间移动时车辆没有磨损，去其他高度的方格将会有数值等同于高度差的磨损，理所当然的是车辆只能前往与当前方格相邻的方格。小程需要从山区左上角的方格到山区右下角的方格，请问他的车辆磨损最少是多少？



// 输入描述
// 第1行是数据n，m，接下来n行各有m个数字，表示对应位置方格的高度h

// 数字间两两空格隔开

// 数据范围：2≤h，n，m≤200。

// 输出描述
// 仅一行，包含一个整数，最小磨损ans。


// 样例输入
// 3 3
// 1 5 3
// 6 7 7
// 1 5 3
// 样例输出
// 10

// 提示
// 小程沿1-> 6-> 7-> 7-> 3的方向移动，磨损值为10。


#include<bits/stdc++.h>
using namespace std;


    int imin = INT_MAX;
    void dfs(vector<vector<int>>& nums,int x,int y,int p){
        if(x==nums.size()-1 && y==nums[0].size()-1){
            imin=std::min(imin,p);
            return;
        }
        int temp=nums[x][y];
        nums[x][y]=INT_MAX;
        int p1=0,p2=0,p3=0,p4=0;
        if(x-1>=0 && x-1<nums.size() && nums[x-1][y]!=INT_MAX){
            p1=nums[x-1][y];
            dfs(nums,x-1,y,p+abs(temp-p1));
        }
        if(x+1>=0 && x+1<nums.size() && nums[x+1][y]!=INT_MAX){
            p2=nums[x+1][y];
            dfs(nums,x+1,y,p+abs(temp-p2));
        }
        if(y-1>=0 && y-1<nums[0].size()&& nums[x][y-1]!=INT_MAX){
            p3=nums[x][y-1];
            dfs(nums,x,y-1,p+abs(temp-p3));
        }
        if(y+1>=0 && y+1<nums[0].size()&& nums[x][y+1]!=INT_MAX){
            p4=nums[x][y+1];
            dfs(nums,x,y+1,p+abs(temp-p4));
        }
        nums[x][y]=temp;
        return;
    }


int main(int argc, char const *argv[])
{
    int n,m;
    while(cin>>n>>m){
        vector<vector<int>> nums(n,vector<int>(m));
        int temp;
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                cin>>temp;
                nums[i][j]=temp;
            }
        }

        int x=0,y=0,p=0;
        dfs(nums,x,y,p);
        cout<<imin<<endl;
    }
    return 0;
}
